package utils;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Handler;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.VideoView;

import java.io.File;
import java.io.IOException;
import java.util.List;

import log.LogManager;
import utils.common.ToastUtil;

/**
 * Created by Administrator on 2016/4/14.
 */
public class RecordVideoUtil implements SurfaceHolder.Callback, MediaRecorder.OnInfoListener,
        MediaRecorder.OnErrorListener {
    private static RecordVideoUtil recordVideoUtil;
    private int frontCamera = 0;// 0是backCamera 1是frontCamera
    private File tempFile;

    private VideoView mVideoView;
    private MediaRecorder mediaRecorder;

    private Camera mCamera;
    private SurfaceHolder mSurfaceHolder;

    private Handler handler = new Handler(); //计时
    private Runnable runnable;

    private int totalTime; //录制长度
    private long totalVolume;//累加的音频幅度，用以检查录音权限
    private static final int CHECK_TIMEPOINT = 1000;//检查录音权限的时间点
    private boolean isRecording = false;
    private static final long CHECK_SIZE = 3 * 1024;//检查权限时的文件大小值
    private Context mContext;
    private int widthSize = 1280;//默认视频大小
    private int heightSize = 720;


    private RecordVideoUtil() {

    }

    public static RecordVideoUtil getInstance() {
        if (null == recordVideoUtil) {
            recordVideoUtil = new RecordVideoUtil();
        }
        return recordVideoUtil;
    }

    /**
     * 计时CHECK_TIMEPOINT 毫秒，用以检查录音权限是否开启
     */
    private void timing() {
        totalTime = 0;
        totalVolume = 0;
        runnable = new Runnable() {
            @Override
            public void run() {
                if (!isRecording) {
                    handler.removeCallbacksAndMessages(null);
                } else {
                    if (totalTime == CHECK_TIMEPOINT) {
                        handler.removeCallbacksAndMessages(null);
                        LogManager.getLogger().w("totalVolume-CHECK_TIMEPOINT", "totalVolume==>" + totalVolume);
                        if (totalVolume == 0) {
                            checkAudioEnable();
                        }
                    } else {
                        totalVolume += mediaRecorder.getMaxAmplitude();
                        LogManager.getLogger().w("totalVolume==>", "" + totalVolume);
                        totalTime += 200;
                        handler.postDelayed(this, 200);
                    }
                }
            }
        };
        handler.postDelayed(runnable, 200);
    }

    /**
     * 检查视频文件大小
     */
    public void checkFileSize() {
        LogManager.getLogger().w("totalVolume-CHECK_SIZE", "FileSizes==>" + FileUtil.getFileSizes(getTempFile()));
        if (FileUtil.getFileSizes(getTempFile()) <= CHECK_SIZE) {
            checkVideoEnable();
        }
    }

    /**
     * 初始化相机(使用前  必须调用)
     *
     * @return true:初始化成功  false:初始化失败
     */
    public boolean initView(Context context, VideoView videoView) {
        this.mContext = context;
        this.mVideoView = videoView;
        mSurfaceHolder = mVideoView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        //        return initCamera();

        return true;
    }

    /**
     * 开始 录制视频
     */
    @SuppressLint("NewApi")
    public boolean startRecording() {
        isRecording = true;
        if (mediaRecorder == null) {
            if (initRecorder()) {
                mediaRecorder.setOnInfoListener(this);
                mediaRecorder.setOnErrorListener(this);
                mediaRecorder.start(); // ???
                timing();
                return true;
            } else {
                return false;
            }
        } else {
            timing();
            try {
                mediaRecorder.setOnInfoListener(this);
                mediaRecorder.setOnErrorListener(this);
                mediaRecorder.start(); // ???
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
    }

    /**
     * 切换前后的录制镜头
     */
    @SuppressLint("NewApi")
    public void switchRecording() {
        // mCamera is the Camera object
        if (mCamera == null) {
            return;
        }
        if (Camera.getNumberOfCameras() >= 2) {
            if (mCamera != null) {
                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
            }
            // "which" is just an integer flag
            switch (frontCamera) {
                case 0:
                    mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
                    frontCamera = 1;
                    break;
                case 1:
                    mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
                    frontCamera = 0;
                    break;
            }
            try {
                // Camera.Parameters parameters = mCamera.getParameters();
                mCamera.lock();
                //                setCameraParams();
                mCamera.setDisplayOrientation(90);
                // mCamera.setParameters(parameters);
                mCamera.setPreviewDisplay(mVideoView.getHolder());
                mCamera.startPreview();
            } catch (IOException exception) {
                mCamera.release();
                mCamera = null;
            }
        }
    }

    public void startPreView() {
        mVideoView.setMediaController(null);
        mVideoView.setVisibility(View.VISIBLE);
        startsPreView();
    }

    /**
     * 开启预览
     */
    private void startsPreView() {
        if (mCamera == null) {
            if (initCamera()) {
                CaremaStartPreView();
            }
        } else {
            CaremaStartPreView();
        }
    }

    /**
     * 开启预览
     */
    private void CaremaStartPreView() {
        try {
            mCamera.setPreviewDisplay(mSurfaceHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            LogManager.getLogger().s("Could not start the preview");
            e.printStackTrace();
        }
    }

    /**
     * 退出界面时  销毁引用(必须调用)
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
    public void stopRecording() {
        isRecording = false;
        if (mediaRecorder != null) {
            mediaRecorder.setOnErrorListener(null);
            mediaRecorder.setOnInfoListener(null);
            mediaRecorder.setPreviewDisplay(null);

            try {
                if (null != mCamera && null != mCamera.getParameters() && mCamera.getParameters().getVideoStabilization()) {
                    mediaRecorder.stop();
                }
            } catch (Exception e) {
                // This can happen if the recorder has already stopped.
                LogManager.getLogger().s("Got IllegalStateException in stopRecording");
            }
        }
        releaseRecorder();
        if (mCamera != null) {
            mCamera.stopPreview();
            releaseCamera();
        }

        if (null != recordVideoUtil) {//释放该静态对象
            recordVideoUtil = null;
        }
    }

    @SuppressLint("NewApi")
    private boolean initRecorder() {
        if (mCamera == null)
            initCamera();
        mVideoView.setVisibility(View.VISIBLE);
        mCamera.stopPreview();
        mediaRecorder = new MediaRecorder();
        mCamera.unlock();
        mediaRecorder.setCamera(mCamera);

        // init
        try {
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

            if (frontCamera == 1) {
                mediaRecorder.setOrientationHint(270);
            } else {
                mediaRecorder.setOrientationHint(90);// 视频旋转
            }
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            // other work
            tempFile = FileUtil.TackVideoFilePath();
            if (tempFile==null){
                LogManager.getLogger().i("initRecord error","创建视频文件出错");
                return false;
            }
            // 设置视频编码方式
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            // 设置音频编码方式
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            mediaRecorder.setOutputFile(tempFile.getPath());
            mediaRecorder.setMaxDuration(30000);
            mediaRecorder.setVideoSize(widthSize, heightSize);// 设置分辨率：
            mediaRecorder.setVideoFrameRate(30);// 这个我把它去掉了，感觉没什么用
            mediaRecorder.setVideoEncodingBitRate(1024 * 1024);// 设置帧频率，然后就清晰了
            mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
            // prepare
            try {
                mediaRecorder.prepare();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return true;
        } catch (Exception e) {
            mediaRecorder = null;
            LogManager.getLogger().e("mediaRecorder.setAudioSource ==>", e.toString());
            checkAudioEnable();
            return false;
        }
    }

    /**
     * 检查语音录制的权限
     */
    private void checkAudioEnable() {
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle("视频录制出错");
        builder.setMessage("请打开录音权限和相机权限后重试");
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ((Activity) mContext).finish();
            }
        });
        builder.setCancelable(false);
        builder.show();
    }

    @SuppressLint("NewApi")
    private boolean initCamera() {
        try {
            if (frontCamera == 0) {
                mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
            } else {
                mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
            }
            Camera.Parameters camParams = mCamera.getParameters();
            camParams.setPreviewSize(widthSize, heightSize);//预览和录制视频的分辨率保持一致
            mCamera.setParameters(camParams);
            mCamera.lock();
            mSurfaceHolder = mVideoView.getHolder();
            mSurfaceHolder.addCallback(this);
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            mCamera.setDisplayOrientation(90);
        } catch (RuntimeException re) {
            LogManager.getLogger().s("Could not initialize the Camera");
            /*if (initCameraErrorLestiner != null) {
                initCameraErrorLestiner.onInitCameraError();
            }*/
            checkAudioEnable();

            //re.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 检查视频录制的权限
     */
    private void checkVideoEnable() {
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle("视频文件保存出错");
        builder.setMessage("请检查录音权限和相机权限后重试");
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ((Activity) mContext).finish();
            }
        });
        builder.show();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        startsPreView();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (mCamera != null) {
            //            setCameraParams();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (mCamera != null) {
            //mCamera.stopPreview();
            //releaseCamera();
        }
    }

    @Override
    public void onError(MediaRecorder mr, int what, int extra) {

    }

    @Override
    public void onInfo(MediaRecorder mr, int what, int extra) {
        LogManager.getLogger().s("got a recording event");
        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
            LogManager.getLogger().s("...max duration reached");
            stopRecording();
            mVideoView.setVisibility(View.GONE);
            if (tempFile == null)
                return;
            /*Bitmap createVideoThumbnail = FileUtil.createVideoThumbnail(tempFile.getAbsolutePath());
            if (createVideoThumbnail != null) {
                imageview.setImageBitmap(createVideoThumbnail);
            }*/
        }
    }


    /**
     * 设置相机参数  对焦
     */
    public void setCameraParams() {
        if (mCamera != null) {
            Camera.Parameters params = mCamera.getParameters();
            List<String> list = params.getSupportedFocusModes();
            if (list.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            }
            params.set("orientation", "portrait");
            mCamera.setParameters(params);
        }
    }

    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
        }
    }

    private void releaseRecorder() {
        if (mediaRecorder != null) {
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }

    public String getTempFile() {
        if (tempFile!=null){
            return tempFile.getAbsolutePath();
        }else {
            ToastUtil.showErrorMsg("初始化视频路径失败，请检查权限后重试");
            return "";
        }
    }
}
